package com.itedge.infrastructure.web.controller.process.impl;

import javax.servlet.http.HttpServletRequest;

import org.springframework.context.MessageSource;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import com.itedge.infrastructure.constants.InfrastructureConstants;
import com.itedge.infrastructure.domain.IProcessEntity;
import com.itedge.infrastructure.service.domain.IProcessEntityService;
import com.itedge.infrastructure.service.process.IProcessService;
import com.itedge.infrastructure.web.controller.impl.AbstractEntityController;
import com.itedge.infrastructure.web.controller.process.IProcessEntityController;

/**
 * Abstract class for all controller on objects of IProcessEntity type.
 * 
 * @author jhe
 *
 * @param <E extends IProcessEntity>
 */
public abstract class AbstractProcessEntityController<E extends IProcessEntity> extends AbstractEntityController<E> 
	implements	IProcessEntityController {

	/** Message source reference */
	protected MessageSource messageSource;   
		
	/** Process service */
	protected IProcessService<E> processService;
	
	/**
	 * Default constructor with process service and process entity service arguments.
	 * 
	 * @param processEntityService
	 * @param processService
	 */
	protected AbstractProcessEntityController(IProcessEntityService<E> processEntityService,
			IProcessService<E> processService, MessageSource messageSource) {
		super(processEntityService);
		this.processService = processService;
		this.messageSource = messageSource;
	}
	
	/**
	 * Return key under which process entity will be added to model.
	 * 
	 * @return model key for entity object
	 */
	protected abstract String getModelKeyForEntity();
	
	/**
	 * Return name of view for showing process entity.
	 * 
	 * @return name of entity view
	 */
	protected abstract String getShowView();
	
	/**
	 * Implementing classes could add additional model values for show view.
	 * 
	 * @param model
	 */
	protected abstract void addModelAttributesForShow(Model model);
	
	@Override
	@RequestMapping(value = "/{id}", method = RequestMethod.GET)
	public String show(@PathVariable("id") Long id, Model model, HttpServletRequest request) {
		E processEntity = this.entityService.findEntity(id);
		model.addAttribute(getModelKeyForEntity(), processEntity);
		Boolean isFromDeletedTask = 
			(Boolean) request.getSession()
				.getAttribute(InfrastructureConstants.SESSION_ATTR_FROM_NON_EXISTING_TASK);
		if(isFromDeletedTask != null && isFromDeletedTask) {
			request.getSession()
				.setAttribute(InfrastructureConstants.SESSION_ATTR_FROM_NON_EXISTING_TASK, null);
    		model.addAttribute(InfrastructureConstants.MODEL_ATTR_TASK_DELETED,
        			messageSource.getMessage(InfrastructureConstants.TASK_DELETED,
    	    		null, InfrastructureConstants.UNDEFINED_MESSAGE, request.getLocale()));
		}
        if (processEntity.getProcessInstanceId() != null) {
        	model.addAttribute("tasks", this.processService
    			.readAllPendingTasksForProcessInstance(processEntity.getProcessInstanceId()));
        	model.addAttribute("completedTasks", 
        			this.processService.readAllCompletedTasksForProcess(processEntity.getProcessInstanceId(), 
    					true, true));
            model.addAttribute("taskHistoryDateTimeFormat", InfrastructureConstants.ISO_DATE_TIME_FORMAT);
        }
        addModelAttributesForShow(model);
		return getShowView();
	}

}
